package com.src.xyzk_personal.config;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import android.util.Log;

public class ComSocket {
    private final static String TAG = "ComSocket";
    private static Socket socket = null;
    private static DataOutputStream dout = null;
    private static DataInputStream din = null;
    private boolean exit = false;
    private boolean m_record = false;  //LOG记录开关
    private LogFile m_log = LogFile.getInstance();    //日志对象

    public ComSocket() {
        // TODO Auto-generated constructor stub
        exit = false;
    }

    void exit() {
        if (Common.Debug) Log.e(TAG, "执行了exit");
        exit = true;
    }

    public boolean ConnectBox(String ip, int port) {
        //建立socket连接
        try {
            socket = new Socket(ip, port);
            dout = new DataOutputStream(socket.getOutputStream());
            din = new DataInputStream(socket.getInputStream());
            Sleep(50);    //实际中刚连上后发数据需要一定延时  确保双方链接初始化完成
            if (Common.Debug) Log.i(TAG, "Socket连接成功!");
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
        if (Common.Debug) Log.i(TAG, "变量状态: exit=" + exit);
        return true;
    }

    //毫秒
    private void Sleep(int times) {
        try {
            Thread.sleep(times, 0);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //设置开始记录
    public void SetStartRecord(String vin) {
        char first = vin.charAt(0);
        if (first < 'A' || first > 'Z') return;
        //m_log = new LogFile(vin);
        if (m_log != null) {
            m_record = true;
            if (Common.Debug) Log.i(TAG, "开始记录日志!");
        } else {
            if (Common.Debug) Log.e(TAG, "创建记录日志失败!");
        }
    }

    //设置CAN线波特率
    public boolean SetCanBaud(long baud) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x06, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00};
        byte[] Ans = new byte[128];
        if (m_log != null)
            m_log.PrintAppend(0, "SetBaud:" + baud);
        //获取波特率
        cmd[8] = (byte) ((baud / 0x10000) & 0xFF);
        cmd[9] = (byte) ((baud / 0x100) & 0xFF);
        cmd[10] = (byte) (baud & 0xFF);
        //计算校验
        cmd[11] = Commonfunc.CalcChechSum(cmd, 4, 11);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
            return true;
        else
            return false;
    }

    //设置P-CAN或B-CAN
    public boolean SetCanMode(int mode) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x04, 0x10, 0x09, 0x00, 0x00};
        byte[] Ans = new byte[128];
        //记录设置CAN
        if (m_log != null)
            m_log.PrintAppend(0, "SetCan:" + mode);
        //
        cmd[8] = (byte) (mode & 0xFF);
        //计算校验
        cmd[9] = Commonfunc.CalcChechSum(cmd, 4, 9);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
            return true;
        else
            return false;
    }

    //设置can过滤
    public boolean SetCanFilter(byte[] Pbuf, int num) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x08, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        byte[] Ans = new byte[128];
        //记录设置CAN ID
        if (m_log != null) {
            m_log.PrintAppend(0, "SetCanID:" + Commonfunc.bytesToHexString(Pbuf, 0, num * 2));
            m_log.setCanId(Pbuf); //设置canID
        }
        //
        cmd[8] = (byte) (num & 0xFF);
        for (int i = 0; i < num * 2; i++) {
            cmd[9 + i] = Pbuf[i];
        }
        //计算校验
        cmd[9 + num * 2] = Commonfunc.CalcChechSum(cmd, 4, 9 + num * 2);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
            return true;
        else
            return false;
    }

    //设置can自动回复
    public boolean SetCanAutoFrame(byte[] Pbuf, int Plen) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x0B, 0x10, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        byte[] Ans = new byte[128];
        for (int i = 0; i < Plen; i++) {
            cmd[8 + i] = Pbuf[i];
        }
        //计算校验
        cmd[8 + Plen] = Commonfunc.CalcChechSum(cmd, 4, 8 + Plen);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
            return true;
        else
            return false;
    }

    //设置时序
    public boolean SetCommunTimer(int P1, int P2, int P3, int P4) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x09, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        byte[] Ans = new byte[128];
        cmd[8] = (byte) (P1 & 0xFF);
        cmd[9] = (byte) ((P2 / 0x100) & 0xFF);
        cmd[10] = (byte) (P2 & 0xFF);
        cmd[11] = (byte) ((P3 / 0x100) & 0xFF);
        cmd[12] = (byte) (P3 & 0xFF);
        cmd[13] = (byte) (P4 & 0xFF);
        //计算校验
        cmd[14] = Commonfunc.CalcChechSum(cmd, 4, 14);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
            return true;
        else
            return false;
    }

    //KWP波特率设置
    public boolean SetKwpBaud(long baud) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x05, 0x10, 0x02, 0x00, 0x00, 0x00};
        byte[] Ans = new byte[128];
        if (m_log != null)
            m_log.PrintAppend(0, "SetkwpBaud:" + baud);
        //获取波特率
        cmd[8] = (byte) ((baud / 0x100) & 0xFF);
        cmd[9] = (byte) (baud & 0xFF);
        //计算校验
        cmd[10] = Commonfunc.CalcChechSum(cmd, 4, 10);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40)))
            return true;
        else
            return false;
    }

    //获取序列号
    public boolean GetSerialNum(byte[] Serialnum, int Psize, byte[] softver) {
        byte[] cmd = new byte[]{0x55, (byte) 0xAA, (byte) 0xC1, (byte) 0xB1, 0x00, 0x03, 0x20, 0x08, 0x00};
        byte[] Ans = new byte[128];
        //计算校验
        cmd[8] = Commonfunc.CalcChechSum(cmd, 4, 8);
        int rlen = SendOneToOne(cmd, cmd.length, Ans, Ans.length, Common.setmaxtime);
        if (rlen > 0 && (Ans[6] == (byte) (cmd[6] + 0x40))) {
            System.arraycopy(Ans, 8, Serialnum, 0, 12);
            System.arraycopy(Ans, 22, softver, 0, 2);
            return true;
        } else
            return false;
    }

    //cmd使用can重发3次,发多帧收多帧
    public int CanSendAndRecvN2N(byte[] Send, int Plen, byte[] Recv, int Psize, int errorcode) {
        int error = 0;
        byte[] Readbuf = new byte[256];
        int i, iRet = 0;
        for (i = 0; i < Common.cmd_freq; i++) {
            iRet = CanSendMore2More(Send, Plen, Readbuf, Readbuf.length, Common.cmdsetmaxtime);
            if (iRet > 0) break;
            if (exit) return 5002;
            Sleep(Common.waittime);
        }
        if (i >= Common.cmd_freq) return 5001; //无响应
        if (Readbuf[1] == (Send[1] + 0x40)) //判断结果
        {
            error = 0;
        } else {
            error = errorcode;
        }
        //复制接收数据
        if (iRet > Psize)
            iRet = Psize - 1;
        System.arraycopy(Readbuf, 0, Recv, 0, iRet);
        return error;
    }

    //cmd CAN 发多帧收多帧
    private int CanSendMore2More(byte[] send, int Plen, byte[] recv, int Psize, int maxtime) {
        byte[] cmd = new byte[]{0x11, 0x31};
        byte[] data = new byte[128];
        //记录发送的数据
        if (m_log != null)
            m_log.PrintAppend(1, Commonfunc.bytesToHexString(send, 0, Plen));
        //超时时间
        data[0] = (byte) ((maxtime / 0x100) & 0xFF);
        data[1] = (byte) (maxtime & 0xFF);
        //添加发送命令的帧数以及帧内容
        int framenum = 0;
        if (Plen <= 8) //单帧
        {
            framenum = 1;
            //添加一帧数据
            for (int i = 0; i < Plen; i++) {
                data[3 + i] = send[i];
            }
        } else    //多帧
        {
            framenum = (Plen + 6) / 7;
            if (framenum > 15) //越界
            {
                return 0;
            }
            for (int i = 0; i < framenum - 1; i++) {
                //添加帧头
                if (i == 0)
                    data[3 + i * 8] = 0x10;
                else
                    data[3 + i * 8] = (byte) (0x20 + i % 0x10);
                //添加内容
                for (int j = 0; j < 7; j++) {
                    data[3 + i * 8 + 1 + j] = send[i * 7 + j];
                }
            }
            //复制最后一帧
            //帧头
            data[3 + (framenum - 1) * 8] = (byte) (((framenum - 1) & 0x0F) + 0x20);
            int lastlen = Plen % 7;
            if (lastlen == 0) lastlen = 7;
            for (int j = 0; j < lastlen; j++) {
                data[3 + (framenum - 1) * 8 + 1 + j] = send[(framenum - 1) * 7 + j];
            }
        }
        //获取帧数
        data[2] = (byte) framenum;
        //组合成命令
        byte[] Sendbuf = new byte[128];
        int Sendlen = addData2Cmd(cmd, data, framenum * 8 + 3, Sendbuf);
        if (Common.Debug) {
            Log.i(TAG, "Sed:" + Commonfunc.bytesToHexString(send, 0, Plen));
            Log.i(TAG, "Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0, Sendlen));
        }
        //发送
        byte[] Readbuf = new byte[128];
        int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
        if (iRet == 9) //只收到发送成功数据
        {
            if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
            {
                //继续接收命令
                iRet = Readdata(Readbuf, Readbuf.length, Common.cmdmaxtime);
                if (iRet > 0) {
                    if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])) {
                        iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
                        //拆开CAN包重组CAN数据
                        if (Readbuf[8] == 1) //单帧
                        {
                            iRet = Readbuf[10] + 1;
                            for (int i = 0; i < iRet; i++)
                                recv[i] = Readbuf[10 + i];
                        } else if (Readbuf[8] > 1) //多帧
                        {
                            iRet = Readbuf[11] + 1;
                            int j;
                            for (int i = 0; i < Readbuf[8]; i++) {
                                for (j = 0; j < 7; j++) {
                                    recv[i * 7 + j] = Readbuf[9 + i * 9 + 2 + j];
                                }
                            }
                        }

                    } else iRet = 0;
                } else
                    iRet = 0;
            } else
                iRet = 0;
        } else if (iRet > 9) //一次性接收回来完了
        {
            if (Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])) {
                iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
                //拆开CAN包重组CAN数据
                if (Readbuf[17] == 1) //单帧
                {
                    iRet = Readbuf[19] + 1;
                    for (int i = 0; i < iRet; i++)
                        recv[i] = Readbuf[19 + i];
                } else if (Readbuf[17] > 1) //多帧
                {
                    iRet = Readbuf[20] + 1;
                    int j;
                    for (int i = 0; i < Readbuf[17]; i++) {
                        for (j = 0; j < 7; j++) {
                            recv[i * 7 + j] = Readbuf[18 + i * 9 + 2 + j];
                        }
                    }
                }
            } else
                iRet = 0;
        } else
            iRet = 0;
        //记录接收的数据
        if (m_log != null && iRet > 0)
            m_log.PrintAppend(2, Commonfunc.bytesToHexString(recv, 0, iRet));
        return iRet;
    }

    //KWP快速初始化
    public int KwpFastConnect(int baud, byte[] send, int Plen, byte[] recv, int Psize, int maxtime, int testtimes, int errorcode) {
        int error = 0;
        int i, iRet = 0;
        //设置波特率
        for (i = 0; i < Common.cmd_freq; i++) {
            if (SetKwpBaud(baud) == true)
                break;
            if (exit) return 5002;
            Sleep(Common.waittime);
        }
        if (i == Common.cmd_freq) return 5001;
        //发送数据
        //先计算校验
        send[Plen - 1] = Commonfunc.CalcChechSum(send, 0, Plen - 1);
        byte[] Readbuf = new byte[256];
        for (i = 0; i < testtimes; i++) {
            iRet = KwpFastInit((byte) 0x19, (byte) 0x19, send, Plen, Readbuf, Readbuf.length, maxtime);
            if (iRet > 0) break;
            if (exit) return 5002;
            Sleep(Common.waittime);
        }
        if (i >= testtimes) return 5001;
        int r_Pos = 5;
        if (Readbuf[2] == 0x80) r_Pos++; //当收到0x80开头的
        int s_Pos = 3;
        if (send[0] == 0x80) s_Pos++;
        if (Readbuf[r_Pos] == (send[s_Pos] + 0x40)) //判断结果
        {
            error = 0;
        } else {
            error = errorcode;
        }
        //复制接收数据
        if (iRet > Psize)
            iRet = Psize - 1;
        System.arraycopy(Readbuf, 0, recv, 0, iRet);
        return error;
    }

    //KWP快速初始化
    private int KwpFastInit(byte Plow, byte Phih, byte[] send, int Plen, byte[] recv, int Psize, int maxtime) {
        byte[] cmd = new byte[]{0x11, 0x01};
        byte[] data = new byte[128];
        //记录发送的数据
        if (m_log != null)
            m_log.PrintAppend(1, Commonfunc.bytesToHexString(send, 0, Plen));
        //超时时间
        data[0] = (byte) ((maxtime / 0x100) & 0xFF);
        data[1] = (byte) (maxtime & 0xFF);
        //拉低拉高时间
        data[2] = Plow;
        data[3] = Phih;
        //添加发送命令
        System.arraycopy(send, 0, data, 4, Plen);
        //组合成命令
        byte[] Sendbuf = new byte[128];
        int Sendlen = addData2Cmd(cmd, data, Plen + 4, Sendbuf);
        if (Common.Debug) {
            Log.i(TAG, "Sed:" + Commonfunc.bytesToHexString(send, 0, Plen));
            Log.i(TAG, "Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0, Sendlen));
        }
        //发送
        byte[] Readbuf = new byte[128];
        int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
        if (iRet == 9) //只收到发送成功数据
        {
            if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
            {
                //继续接收命令
                iRet = Readdata(Readbuf, Readbuf.length, Common.cmdmaxtime);
                if (iRet > 0) {
                    if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])) {
                        iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
                        //拆开数据
                        recv[0] = 0x01;
                        recv[1] = (byte) iRet;
                        System.arraycopy(Readbuf, 8, recv, 2, iRet);
                        iRet += 2;
                    } else iRet = 0;
                } else
                    iRet = 0;
            } else
                iRet = 0;
        } else if (iRet > 9) //一次性接收回来完了
        {
            if (Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])) {
                iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
                //拆开数据
                recv[0] = 0x01;
                recv[1] = (byte) iRet;
                System.arraycopy(Readbuf, 17, recv, 2, iRet);
                iRet += 2;
            } else
                iRet = 0;
        } else
            iRet = 0;
        //记录接收的数据
        if (m_log != null && iRet > 0)
            m_log.PrintAppend(2, Commonfunc.bytesToHexString(recv, 0, iRet));
        return iRet;
    }

    //KWP快速初始化
    public int KwpOneToOne(byte[] send, int Plen, byte[] recv, int Psize, int maxtime, int testtimes, int errorcode) {
        int error = 0;
        int i, iRet = 0;
        //发送数据
        //先计算校验
        send[Plen - 1] = Commonfunc.CalcChechSum(send, 0, Plen - 1);
        byte[] Readbuf = new byte[256];
        for (i = 0; i < testtimes; i++) {
            iRet = KwpSendOne2One(send, Plen, Readbuf, Readbuf.length, maxtime);
            if (iRet > 0) break;
            if (exit) return 5002;
            Sleep(Common.waittime);
        }
        if (i >= testtimes) return 5001;
        int r_Pos = 5;
        if ((Readbuf[2] & 0xFF) == 0x80) r_Pos++; //当收到0x80开头的
        int s_Pos = 3;
        if ((send[0] & 0xFF) == 0x80) s_Pos++;
        if ((Readbuf[r_Pos] & 0xFF) == ((send[s_Pos] & 0xFF) + 0x40)) //判断结果
        {
            error = 0;
        } else {
            error = errorcode;
        }
        //复制接收数据
        if (iRet > Psize)
            iRet = Psize - 1;
        System.arraycopy(Readbuf, 0, recv, 0, iRet);
        return error;
    }

    //KWP快速初始化
    private int KwpSendOne2One(byte[] send, int Plen, byte[] recv, int Psize, int maxtime) {
        byte[] cmd = new byte[]{0x11, 0x02};
        byte[] data = new byte[128];
        //记录发送的数据
        if (m_log != null)
            m_log.PrintAppend(1, Commonfunc.bytesToHexString(send, 0, Plen));
        //超时时间
        data[0] = (byte) ((maxtime / 0x100) & 0xFF);
        data[1] = (byte) (maxtime & 0xFF);
        //添加发送命令
        System.arraycopy(send, 0, data, 2, Plen);
        //组合成命令
        byte[] Sendbuf = new byte[128];
        int Sendlen = addData2Cmd(cmd, data, Plen + 2, Sendbuf);
        if (Common.Debug) {
            Log.i(TAG, "Sed:" + Commonfunc.bytesToHexString(send, 0, Plen));
            Log.i(TAG, "Cmd:" + Commonfunc.bytesToHexString(Sendbuf, 0, Sendlen));
        }
        //发送
        byte[] Readbuf = new byte[256];
        int iRet = SendOneToOne(Sendbuf, Sendlen, Readbuf, Readbuf.length, Common.cmdmaxtime);
        if (iRet == 9) //只收到发送成功数据
        {
            if (Readbuf[0] == 0x55 && (Readbuf[6] == cmd[0]) && (Readbuf[7] == cmd[1])) //命令发送成功
            {
                //继续接收命令
                iRet = Readdata(Readbuf, Readbuf.length, Common.cmdmaxtime);
                if (iRet > 0) {
                    if (Readbuf[0] == 0x55 && ((Readbuf[6] & 0xFF) == cmd[0] + 0x40) && (Readbuf[7] == cmd[1])) {
                        iRet = (Readbuf[4] * 0x100 + Readbuf[5]) - 3;//返回长度
                        //拆开数据
                        recv[0] = 0x01;
                        recv[1] = (byte) iRet;
                        System.arraycopy(Readbuf, 8, recv, 2, iRet);
                        iRet += 2;
                    } else iRet = 0;
                } else
                    iRet = 0;
            } else
                iRet = 0;
        } else if (iRet > 9) //一次性接收回来完了
        {
            if (Readbuf[9] == 0x55 && ((Readbuf[15] & 0xFF) == cmd[0] + 0x40) && (Readbuf[16] == cmd[1])) {
                iRet = (Readbuf[13] * 0x100 + Readbuf[14]) - 3;//返回长度
                //拆开数据
                recv[0] = 0x01;
                recv[1] = (byte) iRet;
                System.arraycopy(Readbuf, 17, recv, 2, iRet);
                iRet += 2;
            } else
                iRet = 0;
        } else
            iRet = 0;
        //记录接收的数据
        if (m_log != null && iRet > 0)
            m_log.PrintAppend(2, Commonfunc.bytesToHexString(recv, 0, iRet));
        return iRet;
    }

    //组合命令
    private int addData2Cmd(byte[] cmd, byte[] Pdata, int Plen, byte[] Pcmdbuf) {
        int cmdlen = 0;
        //这里组成发送的命令
        //先添加发送帧头
        Pcmdbuf[0] = 0x55;
        Pcmdbuf[1] = (byte) 0xAA;
        Pcmdbuf[2] = (byte) 0xC1;
        Pcmdbuf[3] = (byte) 0xB1;
        //计算长度
        cmdlen = 4 + 2 + 2 + Plen + 1;
        //填入长度字节
        Pcmdbuf[4] = (byte) ((cmdlen - 6) / 0x100);
        Pcmdbuf[5] = (byte) ((cmdlen - 6) % 0x100);
        //填入命令字
        Pcmdbuf[6] = cmd[0];
        Pcmdbuf[7] = cmd[1];
        //填入DATA
        for (int i = 0; i < Plen; i++) {
            Pcmdbuf[8 + i] = Pdata[i];
        }
        //计算校验
        Pcmdbuf[cmdlen - 1] = Commonfunc.CalcChechSum(Pcmdbuf, 4, cmdlen - 1);
        return cmdlen;
    }

    //发送数据，发一次收一次
    private int SendOneToOne(byte[] Psend, int Plen, byte[] Precv, int Psize, int maxtime) {
        int len = 0;
        if (dout == null || din == null) return -1; //未连接
        try {
            if (din.available() > 0)  //先清除数据
                din.read(Precv, 0, din.available());
            dout.write(Psend, 0, Plen);
            dout.flush();
            if (Common.Debug) Log.i(TAG, "Send:" + Commonfunc.bytesToHexString(Psend, 0, Plen));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        len = Readdata(Precv, Psize, maxtime);
        return len;
    }

    //只收数据,保证收到完整帧
    private int Readdata(byte[] Precv, int Psize, int maxtime) {
        int len = 0;
        int all_len = 0;
        byte[] buf = new byte[128];
        if (dout == null || din == null) {
            if (Common.Debug) Log.e(TAG, "Readdata exit 1");
            return -1; //未连接
        }
        try {
            long starttime = System.currentTimeMillis(); //获得起始时间
            long endtime = 0;
            while (true) {
                Sleep(1);
                if (dout == null || din == null || exit == true) {
                    if (Common.Debug)
                        Log.e(TAG, "Readdata exit 2" + "dout=" + dout + ";din=" + din + ";exit=" + exit);
                    break; //未连接
                }
//				try {
                len = din.available();
//				} catch (IOException e) {
//					// TODO: handle exception
//					len = 0;
//					if(Common.Debug) Log.e(TAG,"din error!");
//				}
                //len = din.read(buf,0,buf.length);

                if (len > 0) {
                    din.read(Precv, all_len, len);
                    //System.arraycopy(buf, 0, Precv, all_len, len);
                    all_len += len;
                    if (Common.Debug)
                        Log.i(TAG, "Read:" + Commonfunc.bytesToHexString(Precv, 0, len));
                    if ((all_len == 9) && (Precv[5] == 0x03)) //收到下位机回复
                    {
                        //if(Common.Debug) Log.e(TAG,"Readdata exit 3");
                        break;
                    } else if (all_len > 9) //收到超过一帧,或者长帧
                    {
                        if (Precv[5] == 0x03) //表示是多帧
                        {
                            if ((all_len - 9) == ((Precv[14] & 0xFF) + 6)) {
                                //if(Common.Debug) Log.e(TAG,"Readdata exit 4");
                                break;
                            }
                        } else    //长帧
                        {
                            if (all_len == ((Precv[5] & 0xFF) + 6)) {
                                //if(Common.Debug) Log.e(TAG,"Readdata exit 5");
                                break;
                            }
                        }
                    }
                }
                endtime = System.currentTimeMillis();
                if ((endtime - starttime) > maxtime) //超时
                {
                    if (Common.Debug) Log.i(TAG, "超时退出!");
                    break;
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return len;
    }

    //释放
    public void close() {
        exit = true;
        m_record = false;
        if (Common.Debug) Log.i(TAG, "主动退出Socket!" + "exit=" + exit + ";m_record=" + m_record);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            if (dout != null) {
                dout.close();
                dout = null;
            }
            if (din != null) {
                din.close();
                din = null;
            }
            if (socket != null) {
                socket.close();
                socket = null;
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
